package com.tl.web.controller.weixin;
 
import java.io.UnsupportedEncodingException;
import java.net.URLDecoder;
import java.net.URLEncoder;
import java.util.HashMap;
import java.util.Map;

import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestParam;
import org.springframework.web.bind.annotation.ResponseBody;

import com.tl.app.domain.AppUser;
import com.tl.app.service.IAppUserService;
import com.tl.common.core.controller.BaseController;
import com.tl.common.core.domain.AjaxResult;
import com.tl.common.core.domain.entity.SysUser;
import com.tl.common.exception.CustomException;
import com.tl.common.utils.CodeUtil;
import com.tl.common.utils.SecurityUtils;
import com.tl.system.service.ISysConfigService;
import com.tl.system.service.ISysUserService;
import com.tl.wechat.config.Sign;
import com.tl.wechat.config.WechatAccountConfig;
import com.tl.wechat.mp.domain.WechatTemplatOrderCancel;
import com.tl.wechat.mp.domain.WechatTemplatOrderSuccess;
import com.tl.wechat.mp.service.WechatMpService;

import me.chanjar.weixin.common.error.WxErrorException;
import me.chanjar.weixin.mp.api.WxMpService;
import me.chanjar.weixin.mp.bean.result.WxMpOAuth2AccessToken;
import me.chanjar.weixin.mp.bean.result.WxMpUser;
 
@Controller
@RequestMapping("/wechat")
public class WxJsController extends BaseController {
 
    @Autowired
    private WxMpService wxMpService;
 
    @Value("${wechat.mp.projectUrl}")
    private String projectUrl;
    
    @Value("${tl.defaultWxDeptId}")
    private Long defaultWxDeptId;
    
    @Autowired
    private IAppUserService appUserService;
    
    @Autowired
    private ISysUserService userService;
    
    @Autowired
    private WechatMpService wechatMpService;
    
    @Autowired
    private ISysConfigService configService;
    
    @Autowired
    private WechatAccountConfig accountConfig;
    
    private static final Logger log = LoggerFactory.getLogger(WxJsController.class);
    
    
    /**
     * 这个接口是提供给微信验证Token的。
     * @param echostr 你在微信公众号配置页面填写的Token值
     * @return
     */
    @GetMapping("/auth")
    @ResponseBody
    public String auth(@RequestParam(value = "echostr", defaultValue = "suhp") String echostr) {
        return echostr;
    }
    
    /**
     * 测试微信模板消息
     * @param openId
     * @param type
     */
    @GetMapping("/testTemplate")
    public void testTemplate(@RequestParam(value = "openId") String openId,@RequestParam(value = "type") String type) {
    	if(type.equals("1")) {
    		System.out.println("开始发送取消订单");
    		WechatTemplatOrderCancel wtoc=new WechatTemplatOrderCancel();
    		wtoc.setCancelTime("2024-08-16");
    		wtoc.setGoodsName("语音条*12");
    		wtoc.setOrderSn("SJD202408162323");
    		wtoc.setReason("不想要了");
    		wechatMpService.sendOrderCancelTemplate(accountConfig.getDdqxTemplateId(), openId, wtoc);
    		System.out.println("已发送取消订单");
    	}else {
    		System.out.println("开始发送订单成功消息");
    		WechatTemplatOrderSuccess wtos=new WechatTemplatOrderSuccess();
    		wtos.setOrderSn("SJD202408162323");
    		wtos.setServiceTypeName("指定单");
    		wtos.setGoodsName("语音条*12");
    		wtos.setPayPrice("12.54元");
    		wtos.setOrderTime("2024-08-16");
    		wechatMpService.sendOrderSuccessTemplate(accountConfig.getXdcgTemplateId(),openId,wtos);
    		System.out.println("已发送订单成功消息");
    	}
    }
    
    
    @GetMapping("/getWxConfig")
    @ResponseBody
    public AjaxResult getWxConfig(@RequestParam(value = "url") String requestUrl) {
    	Map<String, Object> map=new HashMap<String, Object>();
    	try {
	        //获取jsapi_ticket
	        String jsapiTicket = wxMpService.getJsapiTicket();
	        requestUrl = URLDecoder.decode(requestUrl,"UTF-8");
	        map=Sign.sign(jsapiTicket,requestUrl);
	        map.put("appId",wxMpService.getWxMpConfigStorage().getAppId());
	        return AjaxResult.success(map);
    	} catch (UnsupportedEncodingException | WxErrorException e) {
			e.printStackTrace();
			throw new CustomException("获取微信配置失败！");
		}
    }
    
 
    /**
     *
     * @param returnUrl 要跳转到业务的H5页面的地址
     */
    @GetMapping("/authorize")
    public String authorize(@RequestParam(value = "returnUrl", defaultValue = "http://www.treehole.com.cn") String returnUrl) throws UnsupportedEncodingException {
        log.info("【微信网页授权】进来了，参数={}", returnUrl);
        System.out.println("进来了:" + returnUrl);
        //1. 配置
        //2. 调用方法
        String url = projectUrl + "/wechat/userInfo";
        /*
         * 相当于这种形式
         * URLEncoder.decode(returnUrl,"UTF-8"
         * https://open.weixin.qq.com/connect/oauth2/authorize?appid=APPID&redirect_uri=REDIRECT_URI&response_type=code&scope=SCOPE&state=STATE#wechat_redirect
         */
        // 设置授权作用域，snsapi_base （不弹出授权页面，直接跳转，只能获取用户openid）
        // 或 snsapi_userinfo （弹出授权页面，可通过openid获取用户信息）
        String scope = "snsapi_userinfo";
        String redirectUrl =wxMpService.oauth2buildAuthorizationUrl(url, scope, URLEncoder.encode(returnUrl, "utf-8"));
        log.info("【微信网页授权】获取code,result={}", redirectUrl);
        return "redirect:" + redirectUrl;
    }
    
    
    /**
     * 这个是前端唯一需要调用的接口,前端获取到openid后主动跳转相应页面
     *
     * @author ：suhp
     * @param: ：
     * @return： 重定向
     * 获取用户信息类，最后重定向到指定url
     */
    @GetMapping("/userInfo")
    public String userInfo(@RequestParam("code") String code,@RequestParam("state") String returnUrl) {
        /*当用户同意授权后，会回调所设置的url并把authorization code传过来，
        然后用这个code获得access token，其中也包含用户的openid等信息*/
        WxMpOAuth2AccessToken wxMpOAuth2AccessToken = new WxMpOAuth2AccessToken();
        try {
            //获取access token
            wxMpOAuth2AccessToken = wxMpService.oauth2getAccessToken(code);
            log.info("【AccessToken：】{}", wxMpOAuth2AccessToken.getAccessToken());
        } catch (WxErrorException e) {
            log.error("【微信网页授权】{}", e);
        }
        // 拿到openid
        String openId = wxMpOAuth2AccessToken.getOpenId();
        log.info("【openid：】{}", openId);
        log.info("【我是前端要回调的地址：】{}", returnUrl + "?openId=" + openId);
        // 顺便获取一下用户信息
        WxMpUser wxMpUser = null;
        try {
            wxMpUser = wxMpService.oauth2getUserInfo(wxMpOAuth2AccessToken, "zh_CN");
            //检测系统是否存在
            SysUser su=userService.selectUserByOpenId(openId);
            if(null==su) {
            	String configKey=configService.selectConfigByKey("sys.user.initPassword");
            	su=new SysUser();
            	String appCode=CodeUtil.getAppUserCode("");
            	su.setUserName(appCode);
            	su.setAvatar(wxMpUser.getHeadImgUrl());
            	su.setDeptId(defaultWxDeptId);
            	su.setNickName(wxMpUser.getNickname().trim());
            	su.setPassword(SecurityUtils.encryptPassword(configKey));
            	su.setSex(wxMpUser.getSex().toString());
            	su.setOpenId(openId);
            	userService.insertUser(su);
            	AppUser au=new AppUser();
            	au.setName(su.getNickName());
            	au.setUserId(su.getUserId());
            	au.setSex(wxMpUser.getSex().toString());
//            	switch (su.getSex()) {
//					case "男":
//						au.setSex("0");
//						break;
//					case "女":
//						au.setSex("1");
//						break;
//					default:
//						au.setSex("2");
//						break;
//				}
            	au.setAvatar(su.getAvatar());
            	au.setCode(appCode);
            	appUserService.insertAppUser(au);
            }else {
            	AppUser au=appUserService.selectAppUserByUserId(su.getUserId());
            	au.setName(wxMpUser.getNickname().trim());
            	au.setAvatar(wxMpUser.getHeadImgUrl());
            	au.setSex(wxMpUser.getSex().toString());
//            	switch (wxMpUser.getSex()) {
//					case "男":
//						au.setSex("0");
//						break;
//					case "女":
//						au.setSex("1");
//						break;
//					default:
//						au.setSex("2");
//						break;
//            	}
            	appUserService.updateAppUser(au);
            }
        } catch (WxErrorException e) {
        	log.info("获取用户信息失败");
        }
        log.info("【用户信息：】{}", wxMpUser.toString());
        //注意拼接参数，第一个参数需要加问号，之后参数使用&拼接的问题
        //return "redirect:" + returnUrl + "?openId=" + openId;
        return "redirect:" + returnUrl + "?applyType=wx&openId=" + openId;
    }
}